package com.wzy.service.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzy.common.base.jwtToken.JwtInfo;
import com.wzy.common.base.jwtToken.JwtUtils;
import com.wzy.common.base.redis.RedisUtil;
import com.wzy.common.base.result.R;
import com.wzy.common.base.result.ResultCodeEnum;
import com.wzy.common.base.sms.AliyunSmsSend;
import com.wzy.service.user.dto.PerfectInformationParam;
import com.wzy.service.user.dto.RegisterParam;
import com.wzy.service.user.dto.vo.UserInformationQueryVo;
import com.wzy.service.user.entity.UserInformation;
import com.wzy.service.user.feign.ScheduleService;
import com.wzy.service.user.mapper.UserInformationMapper;
import com.wzy.service.user.service.UserInformationService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wuzhengyu
 * @since 2021-03-13
 */
@Service
public class UserInformationServiceImpl extends ServiceImpl<UserInformationMapper, UserInformation> implements UserInformationService {

    private static final int OK = 1;
    private static final int EXPIRE = 60*60*2;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    UserInformationMapper userInformationMapper;

    @Autowired
    ScheduleService scheduleService;


    /**
     * 发送验证码
     * @param phone
     * @return
     */
    @Override
    public R getVerificationCode(String phone) {
        // 判断号码是否已存在
        //if (phoneNumExist(phone)) {
        //    return R.setResult(ResultCodeEnum.PHONE_REPEAT_ERROR);
        //}
        // 生成验证码
        String verificationCode = createVerificationCode();
        // 存入redis
        if (!redisUtil.set(phone, verificationCode) || !redisUtil.expire(phone,12000)){
            System.out.println("这里报异常");
            return R.error(ResultCodeEnum.REDIS_ERROR);
        }
        // 整合阿里云短信   使用阿里云进行发送
        if (!AliyunSmsSend.sendMessage(phone, verificationCode)){
            return R.error(ResultCodeEnum.SMS_ERROR);
        }
        return R.ok();
    }

    /**
     * 注册用户
     * @param userParam
     * @return
     */
    @Override
    public R register(RegisterParam userParam) {
        // 判断用户名是否重复
        if(userInformationMapper
                .selectOne(Wrappers
                        .<UserInformation>lambdaQuery()
                        .eq(UserInformation::getUsername,userParam.getUsername()))!=null) {
            // 用户名重复
            return R.error(ResultCodeEnum.USERNAME_REPEAT_ERROR);
        }
        // 判断电话号是否重复
        if(userInformationMapper.selectOne(Wrappers.<UserInformation>lambdaQuery().eq(UserInformation::getPhone, userParam.getPhone())) != null) {
            return R.error(ResultCodeEnum.PHONE_REPEAT_ERROR);
        }

        // 判断验证码是否正确
        //String code =redisUtil.get(userParam.getPhone());
        //if(code == null || !code.equals(userParam.getVerificationCode())) {
        //    return R.error(ResultCodeEnum.VERIFICATION_ERROR);
        //}

        // 密码加密md5  需要引入md5库
        String md5Password = DigestUtils.md5DigestAsHex(userParam.getPassword().getBytes());

        // 进行初始化参数设置
        UserInformation userInformation = new UserInformation();
        userInformation.setUsername(userParam.getUsername());
        userInformation.setPhone(userParam.getPhone());
        userInformation.setNickname(userParam.getNickname());
        userInformation.setProfile("https://wzy-image.oss-cn-hangzhou.aliyuncs.com/english_study/head/2021/03/31/33c4cd00-984e-4d78-a81c-3be1829d9fe5.jfif"); // oss图片
        userInformation.setRole("普通用户"); // 用户
        userInformation.setPassword(md5Password);
        userInformation.setEducationalBackground((userParam.getEducationalBackground()));
        userInformation.setGmtCreate(new Date());
        userInformation.setGmtModified(new Date());

        // 存入数据库
        if(userInformationMapper.insert(userInformation) != OK) {
            R.error(ResultCodeEnum.DB_INSERT_ERROR);
        }
        scheduleService.insertSchedule(userInformation.getId().toString());
        // 返回结果
        return R.ok();
    }

    @Override
    public R loginPassword(String username, String password) {
        // 判断用户名是否存在
        UserInformation exist = userInformationMapper
                .selectOne(Wrappers
                        .<UserInformation>lambdaQuery()
                        .eq(UserInformation::getUsername, username));
        if(exist == null) {
            return R.error(ResultCodeEnum.PARAM_ERROR);
        }

        // 判断密码是否正确
        String md5Pwd = DigestUtils.md5DigestAsHex(password.getBytes());
        String dbPwd = exist.getPassword();
        if (!md5Pwd.equals(dbPwd)) {
            return R.error(ResultCodeEnum.PASSWORD_ERROR);
        }
        JwtInfo info = new JwtInfo(exist.getId().toString(), exist.getNickname(), exist.getProfile());
        String jwtToken = JwtUtils.getJwtToken(info, EXPIRE);

        return R.ok().data("token",jwtToken).message("登陆成功!");
    }

    /**
     * 完善用户信息
     * @param param
     * @return
     */
    @Override
    public R perfectInformation(PerfectInformationParam param) {
        // 用户id
        UserInformation userInformation = new UserInformation();
        userInformation.setGmtModified(new Date());
        userInformation.setProfile(param.getProfile());
        userInformation.setNickname(param.getNickname());
        userInformation.setEducationalBackground(param.getEducationBackground());
        userInformation.setSignature(param.getSignature());
        userInformation.setId(param.getUserId());
        Integer result = userInformationMapper.updateById(userInformation);
        if (result == OK) {
            return R.ok();
        } else {
            return R.error(ResultCodeEnum.DB_UPDATE_ERROR);
        }


    }

    @Override
    public R loginVerification(String phone, String code) {
        // 判断是否存在该用户
        UserInformation exist = userInformationMapper
                .selectOne(Wrappers
                        .<UserInformation>lambdaQuery()
                        .eq(UserInformation::getPhone, phone));
        if(exist == null) {
            return R.error(ResultCodeEnum.PARAM_ERROR);
        }
        // 比较验证码
        // 从redis数据库中读取数据
        String redisCode = redisUtil.get(phone);
        if (code.equals(redisCode)) {
            // 相等 登陆成功
            return R.ok().data("user_information", exist);
        } else{
            // 不相等 登陆失败
            return R.error(ResultCodeEnum.VERIFICATION_ERROR);
        }
    }

    @Override
    public IPage<UserInformation> selectPage(Long page, Long limit, UserInformationQueryVo userInformationQueryVo) {
        Page<UserInformation> pageParam = new Page<>(page, limit);
        QueryWrapper<UserInformation> queryWrapper = new QueryWrapper<>();
        //queryWrapper.orderByAsc("sort");

        if (userInformationQueryVo == null){
            return baseMapper.selectPage(pageParam, queryWrapper);
        }

        String username = userInformationQueryVo.getUsername();
        String nickname = userInformationQueryVo.getNickname();
        String phone = userInformationQueryVo.getPhone();
        String gmtCreate = userInformationQueryVo.getGmtCreate();
        String gmtModified = userInformationQueryVo.getGmtModified();
        String educationalBackgroundEnum = userInformationQueryVo.getEducationalBackground();
        String level = userInformationQueryVo.getLevel();
        String userRole = userInformationQueryVo.getRole();
        // 用户名
        if (!StringUtils.isEmpty(username)) {
            //左%会使索引失效
            queryWrapper.likeRight("username", username);
        }
        // 昵称
        if (!StringUtils.isEmpty(nickname)) {
            //左%会使索引失效
            queryWrapper.likeRight("nickname", nickname);
        }
        // 手机号
        if (!StringUtils.isEmpty(phone)) {
            //左%会使索引失效
            queryWrapper.eq("phone", phone);
        }
        // 创建时间
        if (!StringUtils.isEmpty(gmtCreate)) {
            queryWrapper.ge("gmt_create", gmtCreate);
        }
        // 登陆时间
        if (!StringUtils.isEmpty(gmtModified)) {
            queryWrapper.ge("gmt_modified", gmtModified);
        }
        // 学历背景
        if (!StringUtils.isEmpty(educationalBackgroundEnum)) {
            queryWrapper.eq("educational_background", educationalBackgroundEnum);
        }
        // 等级
        if (!StringUtils.isEmpty(level)) {
            queryWrapper.eq("level", level);
        }
        if (!StringUtils.isEmpty(userRole)) {
            queryWrapper.eq("role", userRole);
        }

        // 返回结果
        return baseMapper.selectPage(pageParam, queryWrapper);
    }

    @Override
    public List<UserInformation> exceptAdminList() {
        return userInformationMapper.selectList(Wrappers.<UserInformation>lambdaQuery().ne(UserInformation::getRole, "管理员"));
    }

    /**
     * 查询手机号是否存在
     * @param phone
     * @return
     */
    private boolean phoneNumExist(String phone) {
        QueryWrapper<UserInformation> q = new QueryWrapper<>();
        q.eq("phone",phone);
        //return userInformationMapper.selectOne(Wrappers.<UserInformation>lambdaQuery().eq(UserInformation::getPhone, phone)) == null;
        return userInformationMapper.selectOne(q) != null;
    }

    /**
     * 创建新的验证码
     * @return
     */
    private String createVerificationCode() {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for(int i=0; i<6; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }


}
